/*
一、 闭包的语法结构为 |参数| -> 返回类型 { 函数体 }，支持类型推断和省略返回类型：
    // 无参数闭包
    let greet = || println!("Hello, Rust!");
    greet();

    // 带参数闭包（类型可省略）
    let add = |x, y| x + y;
    let result = add(2, 3); // 返回 5 

    // 显式指定返回类型
    let multiply = |a: i32, b: i32| -> i32 { a * b };

二、闭包的捕获方式
1. 不可变借用（Fn）： 仅读取变量，可多次调用：
    let s = String::from("hello");
    let print = || println!("{}", s); // 不可变借用
    print(); // 允许多次调用

2.可变借用（FnMut）：可修改变量，需闭包本身为 mut：
    let mut count = 0;
    let mut increment = || { count += 1; };
    increment(); // count 变为 1 

3.所有权转移（FnOnce）：通过 move 关键字获取变量所有权，只能调用一次：
    let s = String::from("world");
    let consume = move || { println!("{}", s); };
    consume(); // s 的所有权被转移

三、闭包与函数的对比
特性	   闭包	                  普通函数
名称	   匿名	                   有名称
捕获变量    支持	               不支持
类型	   编译器推断（无显式签名）	显式签名
性能	   零成本抽象（编译为函数）	直接调用
适用场景    高阶函数、回调、异步	固定逻辑

四、闭包的实际应用
1.集合操作，与迭代器结合使用，如 map、filter：
    let numbers = vec![1,2,3];
    let doubled: Vec<_> = numbers.iter().map(|x| x * 2).collect();

2.异步回调​​，在异步任务中传递闭包：
    use std::thread;
    let handle = thread::spawn(move || {
        println!("异步任务执行中");
    });
    handle.join().unwrap();

3.​​高阶函数​​，作为参数或返回值：
    fn make_adder(x: i32) -> impl Fn(i32) -> i32 {
        move |y| x + y
    }
    let add5 = make_adder(5);
    assert_eq!(add5(3), 8);

 */

fn main() {
    println!("Hello, world!");
}

let expensive_closure = |num: u32| -> u32 {
    println!("calculating slowly...");
    thread::sleep(Duration::from_secs(2));
    num
};

fn  add_one_v1   (x: u32) -> u32 { x + 1 }
let add_one_v2 = |x: u32| -> u32 { x + 1 };
let add_one_v3 = |x|             { x + 1 };
let add_one_v4 = |x|               x + 1  ;